#include <dbg.h>

using namespace std;

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        if (matrix.empty()) {
            return {};
        }

        int m = matrix.size();
        int n = matrix[0].size();
        vector<vector<bool>> visited(m, vector<bool>(n));
        vector<int> res(m * n);

        int row = 0;
        int col = 0;
        int directionIndex = 0;
        for (int i = 0; i < m * n; ++i) {
            res[i] = matrix[row][col];
            visited[row][col] = true;
            int nextRow = row + directions[directionIndex][0];
            int nextCol = col + directions[directionIndex][1];
            if (nextRow < 0 || nextRow >= m || nextCol < 0 || nextCol >= n ||
                visited[nextRow][nextCol]) {
                directionIndex = (directionIndex + 1) % 4;
            }
            row += directions[directionIndex][0];
            col += directions[directionIndex][1];
        }

        return res;
    }

private:
    const vector<vector<int>> directions{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
};

int main() {
    Solution s;

    vector<vector<int>> matrix{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};

    dbg(s.spiralOrder(matrix));

    return 0;
}